#include "usermanage.h"
#include "ui_usermanage.h"
#include <QDebug>
#include <QToolButton>
#include <QLabel>
#include <QTime>
#include "project.h"
#include "log4z.h"
#include "authmanager.h"
#include "userlogger.h"

using namespace zsummer::log4z;


UserManage::UserManage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::UserManage)
{
    ui->setupUi(this);
    bdf = BllDataFlow::getInstance();
    sqlHelper = SqlHelper::getInstance();

    //Signals and Slots
    connect(bdf, &BllDataFlow::showAllUsersSignal,this,&UserManage::showAllUsersSlot);
    connect(bdf, &BllDataFlow::showAllRolesSignal,this,&UserManage::showAllRolesSlot);
    connect(bdf, &BllDataFlow::retranslateUiSignal, this, &UserManage::retranslateUiSlot);
    connect(bdf, &BllDataFlow::buildFinishedSignal, this, &UserManage::setWidgetParent);
    connect(bdf, &BllDataFlow::setWidgetVisibleSignal, this, &UserManage::setWidgetVisibleSlot);

    initWidget();
}

UserManage::~UserManage()
{
    delete ui;
}

void UserManage::setWidgetParent()
{
    userAdd->setParent(Project::Instance());
    userModifyRole->setParent(Project::Instance());
    userResetPw->setParent(Project::Instance());
    userDelete->setParent(Project::Instance());
    roleAdd->setParent(Project::Instance());
    roleModify->setParent(Project::Instance());
    roleDelete->setParent(Project::Instance());
}

void UserManage::setWidgetVisibleSlot(int permission)
{
    retranslateTable();
}

void UserManage::on_btnAddUser_clicked()
{
    userAdd->clearInput();
    userAdd->show();
}

void UserManage::showAllUsersSlot(bool scrollToBottom)
{
    QTime startTime = QTime::currentTime();
    QList<User> info = sqlHelper->selectAllUsers();
    int rowCount = info.size();
    int rowHeight = (windowWidth >= 1280) ? 60 : 50;

    for (int r = 0; r < info.size(); r++)
    {// 过滤掉厂家账号
        if (AuthManager::instance()->isManufacturer(info[r].name))
        {
            info.removeAt(r);
            rowCount--;
            r--;
        }
    }

    int columnCount = 5;
    ui->tblwUser->setRowCount(rowCount);
    ui->tblwUser->setColumnCount(columnCount);

    for (int r = 0; r < rowCount; r++)
    {
        ui->tblwUser->setRowHeight(r, rowHeight);
        ui->tblwUser->setItem(r, 0, new QTableWidgetItem(info[r].name)); //user.name
        ui->tblwUser->setItem(r, 1, new QTableWidgetItem(info[r].role)); //user.role
        ui->tblwUser->setItem(r, 2, new QTableWidgetItem(info[r].createDatetime)); //user.createTime

        // user.ison
        QToolButton * btnUse = new QToolButton(this);
        btnUse->setCheckable(true);
        ui->tblwUser->setCellWidget(r, 3, btnUse);
        btnUse->setChecked(info[r].status);
        if(info[r].status)
        {
            btnUse->setStyleSheet(NormalBtnEnableCss);
            btnUse->setText(QString(tr("On")));
        }
        else
        {
            btnUse->setStyleSheet(NormalBtnDisEnableCss);
            btnUse->setText(QString(tr("Off")));
        }

        // user operation
        widget = new QWidget;
        QHBoxLayout *horizontalLayout = new QHBoxLayout(widget);
        horizontalLayout->setSpacing(6);

        QString btnStyleSheet = "QToolButton{border-style:none;color:#00BFFF;border:none;border-image:none;}";
        QString btnDelStyleSheet = "QToolButton{border-style:none;color:#CB0000;border:none;border-image:none;}";
        if (windowWidth >= 1280) {
            btnStyleSheet = "QToolButton{border-style:none;color:#00BFFF;border:none;border-image:none;font-size:20px;}";
            btnDelStyleSheet = "QToolButton{border-style:none;color:#CB0000;border:none;border-image:none;font-size:20px;}";
        }

        if (info[r].name == currentUsername)
        {
            QLabel *lblDisable = new QLabel("/");
            lblDisable->setAlignment(Qt::AlignCenter);
            horizontalLayout->addWidget(lblDisable);
        }
        else
        {
            btnModifyUserRole = new QToolButton(widget);
            btnModifyUserRole->setText(tr("Edit"));

            btnResetPw = new QToolButton(widget);
            btnResetPw->setText(tr("ResetPw"));

            btnDeleteUser = new QToolButton(widget);
            btnDeleteUser->setText(tr("Delete"));

            horizontalLayout->addWidget(btnModifyUserRole);
            horizontalLayout->addWidget(btnResetPw);
            horizontalLayout->addWidget(btnDeleteUser);

            btnModifyUserRole->setStyleSheet(btnStyleSheet);
            btnResetPw->setStyleSheet(btnStyleSheet);
            btnDeleteUser->setStyleSheet(btnDelStyleSheet);

            //signals and slots
            connect(btnUse, &QToolButton::toggled, this, &UserManage::setUserEnable);
            connect(btnModifyUserRole, &QToolButton::clicked, this, &UserManage::modifyUserRole);
            connect(btnResetPw, &QToolButton::clicked, this, &UserManage::resetUserPassword);
            connect(btnDeleteUser, &QToolButton::clicked,this, &UserManage::deleteUser);
        }

        ui->tblwUser->setCellWidget(r, 4, widget);    //user operations available

        // set text align center
        for (int j = 0;j < 3;j++)
        {
            ui->tblwUser->item(r, j)->setTextAlignment(Qt::AlignCenter);
        }
    }

    if (scrollToBottom)
    {
        ui->tblwUser->scrollToBottom();
    }

    QTime endTime = QTime::currentTime();
    int elapsed = startTime.msecsTo(endTime);
    qDebug() << "showAllUsersSlot time: " << elapsed;
    LOGFMTD("showAllUsersSlot time: %d ms",elapsed);
}

void UserManage::showAllRolesSlot(bool scrollToBottom)
{
    QTime startTime = QTime::currentTime();
    QList<Role> info = sqlHelper->selectAllRoles();
    int rowCount = info.size();
    int rowHeight = (windowWidth >= 1280) ? 60 : 50;

    for (int r = 0; r < info.size(); r++)
    {// 过滤掉厂家角色
        if (AuthManager::instance()->isManufacturer(info[r].name))
        {
            info.removeAt(r);
            rowCount--;
            r--;
        }
    }

    int columnCount = 3;
    ui->tblwRole->setRowCount(rowCount);
    ui->tblwRole->setColumnCount(columnCount);

    for (int r = 0; r < rowCount;r++)
    {
        ui->tblwRole->setRowHeight(r, rowHeight);
        ui->tblwRole->setItem(r,0,new QTableWidgetItem(info[r].name)); //role name
        ui->tblwRole->setItem(r,1,new QTableWidgetItem(info[r].createDatetime)); //Create time
        //todo:add modify and delete buttons
        QWidget * widget = new QWidget(this);
        QHBoxLayout * horizontalLayout = new QHBoxLayout(widget);
        horizontalLayout->setSpacing(6);

        if(info[r].name == currentUsername)
        {
            QLabel * lblDisable = new QLabel("/");
            lblDisable->setAlignment(Qt::AlignCenter);
            horizontalLayout->addWidget(lblDisable);
        }
        else
        {
            btnModifyRolePermission = new QToolButton(widget);
            btnModifyRolePermission->setText(QString(tr("Edit")));

            btnDeleteRole = new QToolButton(widget);
            btnDeleteRole->setText(QString(tr("Delete")));

            horizontalLayout->addWidget(btnModifyRolePermission);
            horizontalLayout->addWidget(btnDeleteRole);

            QString btnStyleSheet = "QToolButton{border-style:none;color:#00BFFF;border:none;border-image:none;}";
            QString btnDelStyleSheet = "QToolButton{border-style:none;color:#CB0000;border:none;border-image:none;}";
            if (windowWidth >= 1280) {
                btnStyleSheet = "QToolButton{border-style:none;color:#00BFFF;border:none;border-image:none;font-size:20px;}";
                btnDelStyleSheet = "QToolButton{border-style:none;color:#CB0000;border:none;border-image:none;font-size:20px;}";
            }
            btnModifyRolePermission->setStyleSheet(btnStyleSheet);
            btnDeleteRole->setStyleSheet(btnDelStyleSheet);

            connect(btnModifyRolePermission, &QToolButton::clicked, this,&UserManage::modifyRolePermission);
            connect(btnDeleteRole, &QToolButton::clicked, this,&UserManage::deleteRole);
        }

        ui->tblwRole->setCellWidget(r,2,widget);

        // set text align center
        for (int j = 0;j < 2;j++)
        {
            ui->tblwRole->item(r, j)->setTextAlignment(Qt::AlignCenter);
        }
    }

    if (scrollToBottom)
    {
        ui->tblwRole->scrollToBottom();
    }

    QTime endTime = QTime::currentTime();
    int elapsed = startTime.msecsTo(endTime);
    qDebug() << "showAllRolesSlot time: " << elapsed;
    LOGFMTD("showAllRolesSlot time: %d ms",elapsed);
}

void UserManage::initWidget()
{
    ui->stackedWidget->setCurrentWidget(ui->pgUserList);
    ui->tblwUser->setProperty("noinput",true);//不需要虚拟键盘
    ui->tblwRole->setProperty("noinput",true);//不需要虚拟键盘

    ui->tblwUser->setEditTriggers(QAbstractItemView::NoEditTriggers);//单元格不可编辑
    ui->tblwRole->setEditTriggers(QAbstractItemView::NoEditTriggers);//单元格不可编辑

    int headerHeight = 47;
    ui->tblwUser->horizontalHeader()->setFixedHeight(headerHeight);
    ui->tblwRole->horizontalHeader()->setFixedHeight(headerHeight);

    ui->tblwUser->verticalHeader()->hide();
    ui->tblwRole->verticalHeader()->hide();

    userAdd = new UserAdd(this);
    userModifyRole = new UserModifyRole(this);
    userResetPw = new UserResetPW(this);
    userDelete = new UserDelete(this);

    roleAdd = new RoleAdd(this);
    roleModify = new RoleModify(this);
    roleDelete = new RoleDelete(this);

    if (windowWidth >= 1280) {
        ui->btnAddUser->setMinimumSize(160,80);
        ui->btnAddRole->setMinimumSize(160,80);

        ui->tblwUser->setColumnWidth(0,165);
        ui->tblwUser->setColumnWidth(1,165);
        ui->tblwUser->setColumnWidth(2,250);
        ui->tblwUser->setColumnWidth(3,120);

        ui->tblwRole->setColumnWidth(0,410);
        ui->tblwRole->setColumnWidth(1,320);

        userAdd->setGeometry(0,0,1280,800);
        userAdd->setProperty("cssSize", "large");
        QToolButton *btnIsOn = userAdd->findChild<QToolButton *>("btnIsOn");
        btnIsOn->setMaximumWidth(140);

        userModifyRole->setGeometry(0,0,1280,800);
        userModifyRole->setProperty("cssSize", "large");

        userResetPw->setGeometry(0,0,1280,800);
        userResetPw->setProperty("cssSize", "large");

        userDelete->setGeometry(0,0,1280,800);
        userDelete->setProperty("cssSize", "large");

        roleAdd->setGeometry(0,0,1280,800);
        roleAdd->setProperty("cssSize", "large");

        roleModify->setGeometry(0,0,1280,800);
        roleModify->setProperty("cssSize", "large");

        roleDelete->setGeometry(0,0,1280,800);
        roleDelete->setProperty("cssSize", "large");
    } else {
        ui->tblwUser->setColumnWidth(0,128);
        ui->tblwUser->setColumnWidth(1,142);
        ui->tblwUser->setColumnWidth(2,176);
        ui->tblwUser->setColumnWidth(3,128);

        ui->tblwRole->setColumnWidth(0,269);
        ui->tblwRole->setColumnWidth(1,304);
    }

    ui->tblwUser->horizontalHeader()->setStretchLastSection(true);//最后一个单元格扩展
    ui->tblwRole->horizontalHeader()->setStretchLastSection(true);//最后一个单元格扩展

    retranslateTable();
}

void UserManage::retranslateTable()
{
    showAllUsersSlot();
    showAllRolesSlot();
}

void UserManage::on_btnUserList_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->pgUserList);
}

void UserManage::on_btnRoleManage_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->pgRoleManage);
}

void UserManage::on_btnAddRole_clicked()
{
    roleAdd->clearInput();
    roleAdd->show();
}

void UserManage::modifyRolePermission()
{
    //get selected role
    QToolButton* btnModifyPermission = (QToolButton*)sender();
    //get button's parent widget and its position in tablewidget
    QWidget * parentWidget = btnModifyPermission->parentWidget();
    QPoint parentWidgPos = parentWidget->frameGeometry().topRight();
    QModelIndex tableIndex = ui->tblwRole->indexAt(parentWidgPos);

    int row = tableIndex.row();
    qDebug() << "row = " << row;

    QString roleName = ui->tblwRole->item(row,0)->text();
    //get and show current permissions of the role
    Role role;
    role.name = roleName;
    int permission = sqlHelper->selectRolePermission(role);
    bdf->updatePermissionListWidgetSignal(permission);
    bdf->setLineEditRoleNameSignal(roleName);

    roleModify->show();
}

void UserManage::deleteRole()
{
    //get selected role
    QToolButton* btnDeleteRole = (QToolButton*)sender();
    //get button's parent widget and its position in tablewidget
    QWidget * parentWidget = btnDeleteRole ->parentWidget();
    QPoint parentWidgPos = parentWidget->frameGeometry().topRight();
    QModelIndex tableIndex = ui->tblwRole->indexAt(parentWidgPos);

    int row = tableIndex.row();
    qDebug() << "row = " << row;

    QString roleName = ui->tblwRole->item(row,0)->text();
    //send the role deleted
    Role role;
    role.name = roleName;
    bdf->sendDeletedRole(role);
}

void UserManage::modifyUserRole()
{
    //get selected user
    btnModifyUserRole = (QToolButton*)sender();
    //get button's parent widget and its position in tablewidget
    QWidget * parentWidget = btnModifyUserRole ->parentWidget();
    QPoint parentWidgPos = parentWidget->frameGeometry().topLeft();
    QModelIndex tableIndex = ui->tblwUser->indexAt(parentWidgPos);

    int row = tableIndex.row();
    qDebug() << "row = " << row;
    QString username = ui->tblwUser->item(row, 0)->text();
    User user;
    user.name = username;
    user.role = ui->tblwUser->item(row, 1)->text();
    bdf->sendModifyRoleUser(user);

    userModifyRole->show();
}

void UserManage::resetUserPassword()
{
    //get selected user
    btnResetPw = (QToolButton*)sender();
    //get button's parent widget and its position in tablewidget
    QWidget * parentWidget = btnResetPw ->parentWidget();
    QPoint parentWidgPos = parentWidget->frameGeometry().topLeft();
    QModelIndex tableIndex = ui->tblwUser->indexAt(parentWidgPos);

    int row = tableIndex.row();
    qDebug() << "row = " << row;
    QString username = ui->tblwUser->item(row, 0)->text();
    User user;
    user.name = username;
    user.failLoginTimes = 0;
    bdf->sendResetPwUser(user);

    userResetPw->show();
}

void UserManage::deleteUser()
{
    //get selected user
    btnDeleteUser = (QToolButton*)sender();
    //get button's parent widget and its position in tablewidget
    QWidget * parentWidget = btnDeleteUser ->parentWidget();
    QPoint parentWidgPos = parentWidget->frameGeometry().topLeft();
    QModelIndex tableIndex = ui->tblwUser->indexAt(parentWidgPos);

    int row = tableIndex.row();
    qDebug() << "row = " << row;
    QString username = ui->tblwUser->item(row,0)->text();
    User user;
    user.name = username;
    bdf->sendDeleteUser(user);
}

void UserManage::setUserEnable(bool state)
{
    //get selected user
    QToolButton * btnUse = static_cast<QToolButton*>(sender());
    //get button's position in tablewidget
//    QPoint widgPos = btnUse->frameGeometry().topLeft();
    QPoint widgPos = btnUse->frameGeometry().bottomRight();
    QModelIndex tableIndex = ui->tblwUser->indexAt(widgPos);

    int row = tableIndex.row();
    qDebug() << "setUserEnable ";
    qDebug() << "row = " << row;
    QString username = ui->tblwUser->item(row, 0)->text();
    qDebug() << "username = " << username;
    qDebug() << "state = " << state;
    User user;
    user.name = username;
    user.status = state;
    user.failLoginTimes = 0;

    EttaError ret;
    QString text;
    ret = sqlHelper->setUserEnable(user);

    if(state)
    {
        text = tr("On");
        btnUse->setStyleSheet(NormalBtnEnableCss);
        btnUse->setText(text);
    }
    else
    {
        text = tr("Off");
        btnUse->setStyleSheet(NormalBtnDisEnableCss);
        btnUse->setText(text);
    }

    if (ret == EttaError::OK)
    {
        UserLogger::log(QString(tr("%1 User: %2")).arg(text).arg(user.name));
    }
    else
    {
        UserLogger::error(QString(tr("Fail to %1 User %2")).arg(text).arg(user.name));
    }
}

void UserManage::retranslateUiSlot()
{
    ui->retranslateUi(this);
    retranslateTable();
}
